home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / ImageWriter--Chooser snooper / ChooserSupport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  11.3 KB  |  398 lines  |  [TEXT/MPS ]

  1. /*
  2.     ChooserSupport.c - C code for PACK and LDEF resources used by the Chooser.
  3.     
  4.     Copyright © 1992-1994 Apple Computer, Inc.
  5.     All rights reserved.
  6.  
  7.     10/20/93        dmh        Added GetChooserPopUpValue routine.
  8.     12/20/93        dmh        Sync'd with the shipping 1.0b3 GX driver.
  9.      8/26/94        dmh        Sync'd with the shipping 1.0.1 GX driver.
  10.      8/26/94        dmh        Universalized code.
  11. */
  12.  
  13. #include <Types.h>
  14. #include <QuickDraw.h>
  15. #include <Fonts.h>
  16. #include <Lists.h>
  17. #include <Devices.h>
  18. #include <Resources.h>
  19. #include <Script.h>
  20. #include <ToolUtils.h>
  21. #include <LowMem.h>
  22.  
  23. #include "graphics routines.h"
  24. #include <PrintingDrivers.h>
  25.  
  26. #include <Strings.h>
  27. #include <StdIO.h>
  28.  
  29. extern short GetChooserPopUpValue(char *itemStr);
  30.  
  31.  
  32. // Redefine these calls so that the linker won't give us
  33. // code->data ref errors when we use sprintf.     
  34.  
  35. size_t fwrite (const void *, size_t, size_t, FILE *) { return 0; }
  36. int _flsbuf(unsigned char, FILE *){ return 0; }
  37.  
  38.  
  39. // ------------------------------------------------------------------------
  40. // INTERNAL DEFINES
  41. // ------------------------------------------------------------------------
  42. // Chooser initialize message selector
  43. #define initializeMsg    11
  44.  
  45. // Icon Suite support
  46. #define ttNone        0x0000
  47. #define ttDisabled    0x0001
  48. #define    ttOffline    0x0002
  49. #define ttOpen        0x0003
  50. #define ttSelected     0x4000
  51. #define ttSelectedDisabled    (ttSelected + ttDisabled)
  52. #define ttSelectedOffline    (ttSelected + ttOffline)
  53. #define ttSelectedOpen        (ttSelected + ttOpen)
  54.  
  55. #define ttLabel0    0x0000
  56. #define ttLabel1    0x0100
  57. #define ttLabel2    0x0200
  58. #define ttLabel3    0x0300
  59. #define ttLabel4    0x0400
  60. #define ttLabel5    0x0500
  61. #define ttLabel6    0x0600
  62. #define ttLabel7    0x0700
  63. pascal OSErr PlotIconSuite(const Rect * theRect, short align, short iconTransform, Handle cIcon)
  64.     = {0x303C, 0x0603, 0xABC9};
  65.  
  66. // Copy of the DrawText trap
  67. pascal void OldDrawText(const void *textBuf,short firstByte,short byteCount)
  68.     = 0xA885; 
  69.  
  70. // ------------------------------------------------------------------------
  71. // MAIN CODE FOR PACK
  72. // ------------------------------------------------------------------------
  73. pascal OSErr Device(short message, short caller, StringPtr objName, 
  74.                     StringPtr zoneName, ListHandle theList, long p2)
  75. {
  76.     
  77.     OSErr            anErr = noErr;
  78.     extern Str31     gDriverName;
  79.     StringPtr        pDriverName = &gDriverName;
  80.     extern gxJob    gJob;                        // Declared in our .a file.
  81.     gxJob            *pJob = &gJob;
  82.  
  83.     if (message == initializeMsg)    // InitializeMsg--start up GX
  84.     {
  85.         FCBPBRec    pb;
  86.  
  87.     /*
  88.         Get the name of our driver for GXHandleChooserMessage.
  89.         (The user may have renamed us.)
  90.     */
  91.         pb.ioCompletion     = nil;
  92.         pb.ioNamePtr         = pDriverName;
  93.         pb.ioVRefNum         = 0;
  94.         pb.ioRefNum         = CurResFile();
  95.         pb.ioFCBIndx         = 0;
  96.         anErr = PBGetFCBInfo(&pb, false);
  97.  
  98.     /*
  99.         Clear *pJob, because it hasn't been initialized yet.  That doesn't
  100.         happen until we pass GXHandleChooserMessage an initializeMsg.
  101.     */
  102.         *pJob = nil;
  103.  
  104.     /*
  105.         We need to initialize GX printing so that we can call
  106.         GXHandleChooserMessage.  Since printing requires a graphics
  107.         client, call GXEnterGraphics first.  If there are errors,
  108.         (for example, due to memory limitations), post an alert.
  109.     */
  110.         if (anErr == noErr)
  111.         {
  112.             GXEnterGraphics();
  113.             anErr = GXGetGraphicsError(nil);
  114.             if (anErr == noErr)
  115.             {
  116.                 anErr = GXInitPrinting();
  117.                 if (anErr != noErr)
  118.                     GXExitGraphics();
  119.             }
  120.                 
  121.             if (anErr != noErr)
  122.                 StopAlert(-4095, nil);
  123.         }
  124.     }
  125.  
  126. /*
  127.     If the Chooser hasn't created a job yet, do nothing unless we were
  128.     sent an initializeMsg.  In its default implementation of
  129.     GXHandleChooserMessage, QuickDraw GX will create the job for our
  130.     driver when it receives an initializeMsg.  It will store a reference
  131.     to it in our pJob pointer.
  132.     
  133.     For all other messages, if a job has been created, call
  134.     GXHandleChooserMessage to handle things.
  135. */
  136.     if (anErr == noErr)
  137.     {
  138.         if ((*pJob != nil) || (message == initializeMsg))
  139.         {
  140.             anErr = GXHandleChooserMessage(pJob, pDriverName, message, caller, objName, zoneName, theList, p2);
  141.  
  142.         /*
  143.             Drop into the debugger and display info about the current
  144.             "Connect via" menu item.
  145.         */
  146.             if (anErr == noErr)
  147.             {
  148.                 Str255        pStr, itemStr;
  149.                 short        itemNum = GetChooserPopUpValue(itemStr);
  150.  
  151.                 p2cstr(itemStr);
  152.                 pStr[0] = sprintf(&pStr[1], "menu item = %d, item string = \"%s\".", itemNum, itemStr);
  153.                 DebugStr(pStr);
  154.             }
  155.  
  156.         /*
  157.             If we just got a terminateMsg, and p2 is also terminateMsg, the
  158.             Chooser is closing.  QuickDraw GX just disposed of the gxJob it
  159.             created earlier when GXHandleChooserMessage was passed
  160.             initializeMsg, so we just need to call GXExitPrinting and
  161.             GXExitGraphics to clean up.
  162.             
  163.             Note that we must test the p2 parameter, because the Chooser
  164.             can also send terminateMsg when it wants to empty the device
  165.             list, but not dispose of us.  For example, this will happen
  166.             when the user turns off AppleTalk in the Chooser.
  167.         */
  168.             if ((message == terminateMsg) && (p2 == terminateMsg))
  169.             {
  170.                 GXExitPrinting();
  171.                 GXExitGraphics();
  172.             }
  173.         }
  174.     }
  175.         
  176.     return(anErr);
  177.     
  178. } // Device
  179.  
  180.  
  181. /*    --------------------------------------------------------
  182.     This routine returns the item number and label of the
  183.     current "Connect via" menu item.  If the Chooser window
  184.     is closed, it returns 0 for the item number and "" for
  185.     the item string.
  186.     
  187.     NOTE: This routine is only valid once the Chooser's
  188.     initialize message has been forwarded to
  189.     GXHandleChooserMessage.  The pop-up control is appended
  190.     to the Chooser DITL at that time, so trying to access it
  191.     earlier is not possible.
  192.  
  193.     -------------------------------------------------------- */
  194.  
  195. short GetChooserPopUpValue(Str255 itemStr)
  196. {
  197.     WindowPtr        chooserWindow;
  198.     short            itemNum, popUpItem, itemKind;
  199.     ControlHandle    ctlHandle;
  200.     Rect            itemRect;
  201.     MenuHandle        thePopupMenu;
  202.  
  203. /* If the Chooser window is closed, we'll return 0 for the
  204.    item number and "" for the item string.  This would be
  205.    the case if we came here after being passed a terminate
  206.    event caused by closing the Chooser window. */
  207.  
  208.     *itemStr = 0;
  209.     itemNum = 0;
  210.  
  211.  
  212. /* Get the Chooser window, and count its DITL items.  The
  213.    pop-up menu control was the last control added, so we
  214.    just need to access the last DITL item.  The currently
  215.    selected menu item is stored as the control's value,
  216.    and the pop-up's MenuHandle is the first long in the
  217.    control's data handle.  Return the selected menu item
  218.    and its name. */
  219.  
  220.     chooserWindow = FrontWindow();
  221.     
  222.     if (chooserWindow != nil)
  223.     {
  224.         popUpItem = CountDITL(chooserWindow);
  225.         GetDItem(chooserWindow, popUpItem, &itemKind, (Handle *) &ctlHandle, &itemRect);
  226.         itemNum = GetCtlValue(ctlHandle);
  227.         
  228.         thePopupMenu = *(MenuHandle *) *(*ctlHandle)->contrlData;
  229.         GetItem(thePopupMenu, itemNum, itemStr);
  230.     }
  231.     
  232.     return itemNum;
  233. }
  234.  
  235.  
  236. // ------------------------------------------------------------------------
  237. // ENTRY POINT FOR LDEF
  238. // ------------------------------------------------------------------------
  239.  
  240. pascal void LDEF(
  241.     short         message,        // What operation to perform on list
  242.     Boolean     select,            // Is this cell to be selected or not?
  243.     Rect        *theRect,        // Rectangle of this cell, clipped to window
  244.     Cell        theCell,        // Which cell this is
  245.     short        dataOffset,        // Offset into data for this cell
  246.     short        dataLen,        // Length of data for this cell
  247.     ListHandle    theList)        // The list to act upon
  248. /*
  249.     An LDEF that works in two modes:
  250.         - if the first two characters of the cell are valid AppleTalk NBP names (ie, not ≈ ≈)
  251.           then the LDEF is just a basic text LDEF
  252.         - otherwise, it assumes the data is part of a PortListRec, which is
  253.           a structure for icons with text underneath
  254. */
  255.  
  256. {
  257. #pragma unused (theCell, dataLen)
  258.  
  259.     gxPortListRec        theCellContents;
  260.     Rect                iconRect;
  261.     unsigned char        hiliteMode;
  262.     
  263.     switch (message)
  264.         {
  265.         case lDrawMsg:
  266.         case lHiliteMsg:
  267.         
  268.             // save the data to avoid locking things down
  269.             if (dataLen > sizeof(theCellContents) )
  270.                 dataLen = sizeof(theCellContents);
  271.             BlockMove(((*(**theList).cells) + dataOffset), &theCellContents, dataLen );
  272.             
  273.             // draw the cell as an icon, but only if we see our magic marker at the front
  274.             if ( (theCellContents.firstMarker == '≈') && (theCellContents.secondMarker == '≈') )
  275.                 {
  276.                 // center the icon rect on the list with a top margin of 10 pixels
  277.                 iconRect.top = theRect->top + 10;
  278.                 iconRect.left = theRect->left + ((theRect->right - theRect->left) >> 1) - 16;
  279.                 iconRect.bottom = iconRect.top + 32;
  280.                 iconRect.right = iconRect.left + 32;
  281.                 
  282.                 
  283.                 // draw the icon
  284.                 if (theCellContents.iconSuiteHandle != nil)
  285.                     PlotIconSuite(&iconRect,
  286.                             ttNone, (select) ? ttSelected: ttNone,
  287.                             theCellContents.iconSuiteHandle);
  288.                             
  289.                 // Get the general area under the icon in which to draw the label
  290.                 iconRect.left = theRect->left + 2;
  291.                 iconRect.right = iconRect.left + (**theList).cellSize.h - 2;
  292.                 iconRect.top = iconRect.bottom + 2;
  293.                 iconRect.bottom = theRect->bottom;
  294.     
  295.                 // use a nice small font for the label            
  296.                 TextFont(applFont);
  297.                 TextSize(9);
  298.                 
  299.                     {
  300.                     short        labelWidth;
  301.                     short        rectWidth;
  302.                     short        labelHeight;
  303.                     FontInfo    theInfo;
  304.                 
  305.                     // Get rid of any text that was there before
  306.                     EraseRect(&iconRect);
  307.                     iconRect.top += 2;
  308.                     
  309.                     // compute the height of the label                    
  310.                     GetFontInfo(&theInfo);
  311.                     labelHeight = theInfo.ascent + theInfo.leading;
  312.                     
  313.                     // compute where to draw the text
  314.                     iconRect.bottom = iconRect.top + labelHeight;
  315.                     rectWidth = iconRect.right-iconRect.left;
  316.                     
  317.                     // truncate the string to fit within the box
  318.                     TruncString(rectWidth, theCellContents.iconName, smTruncEnd);
  319.                     
  320.                     // compute the new width of the string
  321.                     labelWidth = StringWidth(theCellContents.iconName);
  322.                     
  323.                     // center the string, draw it
  324.                     iconRect.left += (rectWidth >> 1) - (labelWidth >> 1);
  325.                     MoveTo(iconRect.left, iconRect.bottom);
  326.                     DrawString(theCellContents.iconName);
  327.                     
  328.                     if (select)
  329.                         {
  330.                         // compute right and lower edge of box bounding the text we just drew
  331.                         iconRect.right = iconRect.left + labelWidth;
  332.                         iconRect.bottom += theInfo.descent;
  333.                         
  334.                         // outset it, and invert it to select it
  335.                         InsetRect(&iconRect, -1, -1);
  336.                         hiliteMode = LMGetHiliteMode();
  337.                         BitClr(&hiliteMode, pHiliteBit);
  338.                         LMSetHiliteMode(hiliteMode);
  339.                         InvertRect(&iconRect);
  340.                         }
  341.                     }
  342.                     
  343.                 TextFont(applFont);
  344.                 TextSize(0);
  345.                 }
  346.             else
  347.                 {
  348.                 // how boring!  It's only text
  349.                 FontInfo    theInfo;
  350.                 Rect        ourRect;
  351.                 short        cellWidth;
  352.                 
  353.                 // add a margin to the rectangle
  354.                 ourRect = *theRect;
  355.                 ourRect.left += 4;
  356.                 --ourRect.right;
  357.                 cellWidth = ourRect.right - ourRect.left;
  358.                 
  359.                 // erase the rectangle
  360.                 GetFontInfo(&theInfo);
  361.                 EraseRect(theRect);
  362.                 MoveTo(ourRect.left, ourRect.bottom - theInfo.descent);
  363.                 
  364.                 // hey, you can't park that string here -- it's too big!
  365.                 if (TextWidth((Ptr) &theCellContents, 0, dataLen) > cellWidth )
  366.                     {
  367.                     // condense the text first
  368.                     TextFace(condense);
  369.                     
  370.                     // then truncate afterwards
  371.                     TruncText(cellWidth, (Ptr) &theCellContents, &dataLen, smTruncEnd);
  372.                     }
  373.                     
  374.                 // those darn other languages!
  375.                 if (GetSysJust() == teJustRight)
  376.                     Move(cellWidth-TextWidth((Ptr) &theCellContents, 0, dataLen) , 0);
  377.                     
  378.                 OldDrawText((Ptr) &theCellContents, 0, dataLen);
  379.                 
  380.                 // if selected, invert it
  381.                 if (select)
  382.                     {
  383.                     hiliteMode = LMGetHiliteMode();
  384.                     BitClr(&hiliteMode, pHiliteBit);
  385.                     LMSetHiliteMode(hiliteMode);
  386.                     InvertRect(theRect);
  387.                     }
  388.                     
  389.                 // normal text again
  390.                 TextFace(normal);
  391.                 }
  392.                 
  393.             break;
  394.             
  395.         } // switch
  396.         
  397. } // LDEF
  398.